package com.vedana.bankmobile.dao.impl;

import java.util.ArrayList;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Transaction;
import com.vedana.bankmobile.dao.AccountDao;
import com.vedana.bankmobile.shared.Account;

/**
 * GAE Datastore DAO class for customers.
 * 
 * @author Didier MOISE
 *
 */
public class AccountDatastoreDao implements AccountDao {
	private DatastoreService datastore;

	/**
	 * Constructor
	 * 
	 * @param datastore Datastore Service.
	 */
	public AccountDatastoreDao(DatastoreService datastore) {
		this.datastore = datastore;
	}

	@Override
	public void addAccount(Account account) {
		Transaction tx = datastore.beginTransaction();

		Entity entity = accountToNewEntity(account);

		datastore.put(tx, entity);
		tx.commit();
	}

	@Override
	public List<Account> listAccounts(long customerId) {
		ArrayList<Account> result = new ArrayList<Account>();
		
		Key customerKey = KeyFactory.createKey("Customer", customerId);
		
		Query query = new Query("Account");
		query.addFilter("customer", Query.FilterOperator.EQUAL, customerKey);
		PreparedQuery pq = datastore.prepare(query);

		for (Entity entity : pq.asIterable()) {
			Account account = entityToAccount(entity);
			result.add(account);
		}
		
		return result;
	}

	/**
	 * Convert GAE entity to account object
	 * @param entity
	 * @return
	 */
	private Account entityToAccount(Entity entity) {
		Account account = new Account();
		
		account.setId(entity.getKey().getId());
		account.setLabel((String)entity.getProperty("label"));
		Object balance =  entity.getProperty("balance");
		account.setBalance((Double)balance);
		Key customerKey = (Key)entity.getProperty("customer");
		account.setCustomerId(customerKey.getId());
		
		return account;
	}

	/**
	 * Convert account object to new GAE entity
	 * @param account Account object
	 * @return GAE entity
	 */
	private Entity accountToNewEntity(Account account) {
		Key key = KeyFactory.createKey("Account", account.getId());

		Entity entity = new Entity(key);
		entity.setProperty("label", account.getLabel());
		entity.setProperty("balance", account.getBalance());
		entity.setProperty("customer", KeyFactory.createKey("Customer", account.getCustomerId()));
		
		return entity;
	}
}
